Skip to content

Update dlclive requirement & add deploy workflow#48

Merged
C-Achard merged 63 commits intocy/pre-release-fixes-2.0from
cy/update-install
Feb 25, 2026
Merged

Update dlclive requirement & add deploy workflow#48
C-Achard merged 63 commits intocy/pre-release-fixes-2.0from
cy/update-install

Conversation

@C-Achard
Copy link

@C-Achard C-Achard commented Feb 16, 2026

Release preparation

  • Pins DLCLive requirement to v1.1.0, which includes both the torch and tensorflow pipelines.
  • Adds a deploy workflow similar to DeepLabCut-live
    • Deploy job to PyPi behaves exactly the same as the DLC-live job
    • Additionally runs an extra, separate job on PRs to ensure the package can be built and installed on all supported Python versions (smoke test), also before deployment
  • Rename testing workflow for clarity

This pull request introduces a new GitHub Actions workflow for publishing to PyPI and updates the deeplabcut-live dependency throughout the project to version 1.1, replacing the previous requirement for version 2 or higher.

CI/CD Improvements:

  • Added a new workflow file .github/workflows/python-package.yml to automate building and publishing the package to PyPI on tag pushes, with dependency caching and environment setup.

Dependency Management:

  • Updated the main dependency on deeplabcut-live in pyproject.toml to ==1.1 to ensure compatbile packages (esp. torch) are available

Replace flexible >=2 specifiers with an exact deeplabcut-live==1.1.0 for the main dependency and its [pytorch] and [tf] extras in pyproject.toml. This pins the package (and its included extras like timm and scipy) to a known compatible release to avoid missing-dependency or compatibility issues.
@C-Achard C-Achard self-assigned this Feb 16, 2026
@C-Achard C-Achard added the packaging Related to project packaging and release label Feb 16, 2026
@C-Achard C-Achard changed the base branch from master to cy/pre-release-fixes-2.0 February 16, 2026 18:43
Add a new GitHub Actions workflow (python-package.yml) to build and publish packages to PyPI. The workflow triggers on tag pushes (v*.*.*) and on PR events, sets up Python, caches pip, installs build tooling (build, twine, packaging), builds the package, and uploads artifacts to PyPI using TWINE_API_KEY. Also rename .github/workflows/ci.yml to .github/workflows/testing-ci.yml to clarify CI purpose.
@C-Achard C-Achard changed the title Update dlclive requirement Update dlclive requirement & add deploy workflow Feb 16, 2026
Rename workflow and split into a build/validate job and a gated publish job. Add a Python matrix (3.10–3.12), cache keyed by matrix python-version, and update checkout/setup/cache action usages. Build sdist/wheel, run twine check, inspect dist contents, and perform a smoke install from the built wheel (with a best-effort CLI check). Publish step now runs only for tag pushes like vX.Y.Z and uploads with twine using the TWINE_API_KEY secret.
Replace dynamic = ["version"] with an explicit version = "2.0.0rc0" placeholder in pyproject.toml. This makes the package version static (release candidate) for packaging/CI needs; update the placeholder as appropriate for final releases.
@C-Achard C-Achard requested a review from deruyter92 February 16, 2026 19:53
Clarify package description to mention pose estimation experiments with DeepLabCut; fix authors by splitting the previous entry into two distinct authors (M-Lab of Adaptive Intelligence and Mathis Group for Computational Neuroscience and AI) with their respective emails; add a FIXME comment to the Documentation URL to mark docs as a placeholder.
Add a comment in the Python CI workflow recommending inclusion of the lock file for caching and validation. Update the smoke-test step to install the built wheel along with its dependencies by removing `--no-deps`. Also include minor whitespace cleanup.
@C-Achard C-Achard linked an issue Feb 16, 2026 that may be closed by this pull request
17 tasks
Introduce dlclivegui.assets.ascii_art: a cross-platform, CI-safe ASCII/ANSI art generator using OpenCV and numpy (alpha compositing, content cropping, resizing, color modes, and terminal detection). Integrate it into main: add argparse with a --no-art flag, print a startup banner (unless disabled), and use the art helper for help text. Fix QApplication SIGINT keepalive timer handling (avoid duplicate timers and stop existing one before replacing). Change default SHOW_SPLASH to False in theme.py and update tests to restore SHOW_SPLASH=True via an autouse fixture so existing splash-dependent tests continue to pass.
Fix a small header comment in dlclivegui/assets/ascii_art.py and add dlclivegui/assets/* to coverage omit. Expand tests/gui/test_app_entrypoint.py with extensive unit tests for dlclivegui.assets.ascii_art (terminal/ANSI behavior, image helpers, rendering, generate/print API, and help banner), including TTY/NOTTY fixtures, image fixtures (using OpenCV, skipping if missing), and helpers for deterministic terminal sizing. Also adjust imports in the test to reference dlclivegui.assets.ascii_art.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request prepares the DeepLabCut-Live GUI package for release by updating dependencies, adding CI/CD workflows, and enhancing the CLI with ASCII art branding. The changes pin the deeplabcut-live dependency to version 1.1.0 (which includes both PyTorch and TensorFlow pipelines), introduce automated testing and deployment workflows, and add a terminal-based ASCII art banner for improved user experience.

Changes:

  • Pins deeplabcut-live dependency to version 1.1.0 with exact version matching (==1.1) across all optional dependencies
  • Adds GitHub Actions workflows for continuous integration (testing-ci.yml) and package deployment to PyPI (python-package.yml)
  • Introduces ASCII art rendering functionality for terminal branding with cross-platform support and ANSI color handling
  • Updates project metadata (version, description, authors) and disables splash screen by default

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
pyproject.toml Updates deeplabcut-live dependency to ==1.1, sets version to 2.0.0rc0, updates author information, and adds assets directory to coverage exclusions
.github/workflows/testing-ci.yml New CI workflow for running unit and smoke tests across Python 3.10-3.12 on multiple OS platforms with coverage reporting
.github/workflows/python-package.yml New deployment workflow for building, validating, and publishing packages to PyPI on version tags, with smoke testing on PRs
tox.ini Changes from wheel-based package install to editable install (use_develop=true) for faster development iteration
dlclivegui/main.py Adds argparse integration with ASCII art help description, startup print messages, and refactors signal timer handling
dlclivegui/gui/theme.py Disables splash screen by default (SHOW_SPLASH = False)
dlclivegui/assets/ascii_art.py New module providing terminal ASCII art rendering with OpenCV, supporting ANSI colors, transparency, and cross-platform terminal detection
tests/gui/test_app_entrypoint.py Adds comprehensive tests for ASCII art functionality covering terminal detection, image processing, rendering, and help text generation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Update GitHub Actions usages to actions/checkout@v6 and actions/setup-python@v6 in format and python-package workflows for consistency and newer runner support. Improve the python-package workflow's CLI smoke test to explicitly check for the 'dlclivegui' entry point, run its --help when present, and fail the job if the help command returns non-zero—providing clearer diagnostics instead of silently continuing.
Add a __version__ = "2.0.0rc0" placeholder in dlclivegui/__init__.py and update pyproject.toml to use dynamic = ["version"] instead of a hardcoded version field. This makes the project metadata pull the version from the package source rather than storing it twice.
Wrap ASCII-art generation in a try/except to avoid crashing when the asset or terminal ops fail (catch FileNotFoundError, RuntimeError, OSError and fall back to no banner). Add a clarifying comment for the Windows ANSI os.system("") workaround. In argument parsing, allow parse_args to accept argv, detect --no-art early, safely build the help description with a fallback default and log a warning on failure. Replace startup prints with logging.info and use the computed description for argparse. These changes make startup more robust and avoid surprising exceptions when ASCII art cannot be produced.
Replace the autouse fixture with explicit fixtures to toggle dlclivegui.gui.theme.SHOW_SPLASH per-test. Adds set_use_splash_true and set_use_splash_false fixtures, updates tests to accept them, and removes the manual SHOW_SPLASH override in test_main_without_splash. Also fixes a comment typo (thems.py -> theme.py) to make splash behavior explicit and avoid cross-test side effects.
Improve ASCII art rendering performance by replacing per-pixel Python loops with vectorized operations and a byte-level cache. _map_luminance_to_chars now uses a numpy char LUT and joins rows from a (H,W) array of 1-char strings. _color_ascii_lines avoids cv.split and per-pixel f-strings: it computes luminance in float, uses a uint16 index map, packs RGB into a uint32 color key, and caches formatted ANSI-colored byte sequences keyed by (color<<8)|idx. Lines are built as bytearrays and decoded once. Functionality/formatting is preserved while reducing Python-level overhead.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 9 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

"CameraConfigDialog",
"main",
]
__version__ = "2.0.0rc0" # PLACEHOLDER
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__version__ is marked as # PLACEHOLDER. If release automation (or importlib.metadata.version) is expected to reflect the published version, this placeholder should be replaced with the real versioning strategy (or removed in favor of a single authoritative source).

Suggested change
__version__ = "2.0.0rc0" # PLACEHOLDER
__version__ = "2.0.0rc0"

Copilot uses AI. Check for mistakes.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving open as reminder

Add a setuptools dynamic version entry in pyproject.toml so package version is taken from dlclivegui.__version__. Also include package-data for dlclivegui.assets.

Refactor tests/gui/test_app_entrypoint.py to import cv2 at module level and skip the test module early when OpenCV is not available (removed a duplicated try/except). Tighten the assertion in test_generate_ascii_lines_crop_alpha to compare the actual generated ASCII content (lines) rather than only lengths, and clean up related comments.
Replace the hardcoded 'pytorch' model_type with a value inferred from the selected model file. main_window.py now reads the model_path into a local variable and uses DLCLiveProcessor.get_model_backend(model_path) when building DLCProcessorSettings. dlc_processor.py imports Engine from dlclive and adds a static get_model_backend method that returns Engine.from_model_path(model_path).value. Preserves existing config fields and error handling.
Introduce a temporary dlclivegui.temp package with an Engine enum to detect model engines. engine.py provides Engine.TENSORFLOW and Engine.PYTORCH plus helpers from_model_type and from_model_path (checks extensions/pose_cfg.yaml and existence). Add __init__.py and update dlclivegui/services/dlc_processor.py to import Engine from dlclivegui.temp (with a TODO to switch to the upstream dlclive package when available).
Introduce a temporary Engine enum and expose it via dlclivegui.temp to standardize model engine types. Update DLCProcessorSettings to use the Engine enum for model_type. Improve model backend detection in the main window by calling DLCLiveProcessor.get_model_backend and raising a clear error if detection fails; tighten file dialog filters to focus on PyTorch models. Enhance engine detection to recognize .pth files. Minor import cleanup in dlc_processor and a clarifying test comment about timeouts to reduce flakiness in CI.
Switch DLCProcessorSettings.model_type default from a raw string to the Engine enum (Engine.PYTORCH) and change DLCLiveProcessor.get_model_backend to return an Engine instead of a string for stronger typing. Update the GUI to validate empty model path input, reuse the resolved model backend (model_bknd) when building settings, improve the backend-detection error message, and allow selecting any file/directory in the model file dialog (adjusted name filter label for TensorFlow model directories). Also fix a relative import in dlclivegui.temp.__init__.py. Note: this changes the get_model_backend return type (callers expecting a string must use .value if needed).
Adapt tests to recent refactors and improve CI reliability:

- tests/gui/test_ascii_art.py: use LOGO_ALPHA instead of ASCII_IMAGE_PATH, switch color arg from "always" to "auto", and relax the non-TTY assertion to check for the description substring.
- tests/gui/test_main.py: make test_start_inference_emits_pose use tmp_path to create a dummy_model.pt file and set the model path to that file so the existence check passes.
- tox.ini: set QT_OPENGL=software to reduce OpenGL/CI flakiness, and comment out the [testenv:lint] section (also remove lint from the py312 env mapping).

These changes fix tests broken by the logo variable rename and improve test stability in CI environments.
Stop importing and exporting GUI and multi-camera controller symbols at package level to avoid import-time side effects. Removed imports of CameraConfigDialog, DLCLiveMainWindow, MultiCameraController and MultiFrameData from dlclivegui.__init__ and removed those names from __all__. The top-level export list keeps "main" (callers should import GUI/controller types from their modules when needed).
Install Qt/OpenGL runtime dependencies on Ubuntu CI runners (libegl1, libgl1, libopengl0, libxkbcommon-x11-0, libxcb-cursor0) so tests that require OpenGL/Qt can run in the workflow. Also restrict the Codecov upload step to push events on refs/heads/main to avoid uploading coverage for other event types or branches.
Introduce explicit scan state and tidy worker APIs for camera discovery.

- Add CameraScanState enum and use it as single source of truth in CameraConfigDialog (_scan_state).
- Replace ad-hoc worker checks with _set_scan_state, _finish_scan and _cleanup_scan_worker to manage UI overlays, progress/cancel controls and stability guarantees.
- Add request_scan_cancel() to request interruption and handle canceled/result flows; DetectCamerasWorker now emits result (even empty) and canceled when interrupted.
- Simplify QThread usage: remove custom finished signals, add typing annotations and clearer run() signatures in loaders; adjust worker signals (canceled) and small API refinements (request_cancel return types).
- Update UI hookup (ui_blocks) to call request_scan_cancel instead of private handler.
- Update unit and e2e tests to follow new scan lifecycle (wait for scan_started/scan_finished, helper _run_scan_and_wait, and scan state assertions).

Files changed: camera_config_dialog.py, loaders.py, ui_blocks.py and related tests to match the new scan lifecycle and worker behaviour.
Allow Codecov uploads for pushes and pull requests targeting main by loosening the workflow condition. Export the package's main entry (from .main import main) in dlclivegui.__init__ so the CLI/function is exposed. Add tox and tox-gh-actions to the test extras in pyproject.toml. Tidy tox.ini by adding a comment that linting is handled by pre-commit/format workflow and removing an optional tox-gh-actions helper section.
Coerce DLCProcessorSettings.model_type to a lowercase string (accepting Enum or string inputs) and validate allowed backends (pytorch, tensorflow). Update UI to handle TensorFlow .pb models by using the parent directory for DLCLive, restrict file dialog to existing files, add existence checks and backend detection when selecting a model. Improve ModelPathStore: robust path normalization, separate helpers for existing file/dir checks, smarter save/load/resolve logic, and better start-dir/suggest-file heuristics. Minor cleanup: remove duplicate import and clarify a TF model detection comment in engine.
Update tests in tests/utils/test_settings_store.py to exercise ModelPathStore normalization more robustly: use tmp_path to create real directories and files, assert _norm_existing_dir and _norm_existing_path return existing absolute paths (and that they are dir/file respectively), and handle None via _norm_existing_* helpers. Also adjust suggest_start_dir test to make cwd invalid by monkeypatching Path.cwd so the fallback to home is exercised. Removed the previous unreliable expanduser assertion.
Introduce a concurrency block to the testing CI workflow so runs for the same PR are grouped and previous in-progress jobs are cancelled when a new update is pushed. The group is keyed by workflow and pull request number (ci-${{ github.workflow }}-pr-${{ github.event.pull_request.number }}) to avoid redundant CI runs and save resources.
Introduce Engine helpers (is_pytorch_model_path, is_tensorflow_model_dir_path) and centralize model-file/TF-dir detection. Replace the old is_model_file usage with these helpers across settings_store and main_window, fixing a bug in suffix checking and ensuring .pb TensorFlow models are validated via their parent directory. Remove legacy is_model_file from utils. Also update camera UI to expect dlg.request_scan_cancel instead of _on_scan_cancel, refine scan-cancel test synchronization, and add/adjust unit tests to cover the new Engine detection logic.
Add sender() checks and debug logs to scan-related handlers so signals from old/stale scan workers are ignored. Update _is_scan_running to also consider the worker's isRunning() state. Only call _finish_scan("cancel") when there is no active worker to avoid prematurely finishing cancellation. These changes reduce race conditions when restarting/canceling camera scans and ensure UI reflects the current worker's state.
Update tests/utils/test_utils.py to import Engine from dlclivegui.temp instead of dlclivegui.temp.engine. Aligns the test import with the package re-export or module relocation so tests reference the correct top-level import.
Copy link
Author

@C-Achard C-Achard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note : tests will fail until #54 is merged, which is expected.

Ensure model_check_path is set for non-.pb selections before calling DLCLiveProcessor.get_model_backend. .pb files still use the parent directory (TensorFlow expectation); other file types now pass the file path itself to avoid using an undefined or incorrect path.
Introduce a ModelType Literal type ("pytorch" | "tensorflow") and change DLCProcessorSettings.model_type from a plain str to this constrained type, keeping the default as "pytorch". This ensures pydantic validation enforces allowed model backends.
Set a static version (2.0.0rc1) in pyproject.toml and remove the dynamic setuptools configuration that read dlclivegui.__version__. Also remove the placeholder __version__ from dlclivegui/__init__.py so version metadata is centralized in pyproject.toml.
Introduce a cti_files_source marker (auto/user) and wiring to track whether CTI file lists were user-specified or auto-discovered. Treat legacy top-level properties.cti_file(s) as strict user overrides; treat properties.gentl.cti_file(s) as either an auto-cache (falls back to discovery if stale) or a user override depending on the marker. Persist the resolved source back into the namespace when resolving CTIs, and update harvester-selection/rebind logic to fall back to discovery when auto-cached CTIs are stale while still raising for strict user overrides. Also add a small import and internal field (_cti_files_source_used) to track the chosen source, plus logging when falling back from a stale auto-cache.
Add preflight checks, pattern validation and safer globbing for GenTL (.cti) discovery and loading. Renamed default CTI pattern constant to _LEGACY_DEFAULT_CTI_PATTERNS (Windows-only comment) and imported Path. Introduced _cti_preflight to detect missing/locked/permissioned files before Harvester.add_file and applied it where CTIs are loaded (skipping and logging problematic entries). Harden gentl_discovery with: redact-able diagnostics.summarize, _validate_glob_pattern, bounded _glob_limited, static-prefix checks, allowed-roots option and new discover_cti_files params (allow_globs, root_globs_allowed, max_glob_hits_per_pattern) to limit expensive scans. Also adjusted Harvester.update failure handling to treat update errors as discovery failures (return empty loaded list) and improved logging messages for discovery/load failures.
Introduce a single _expand_user_and_env() helper to consistently expand environment variables and '~', and use it across path normalization and glob validation. Update _normalize_path() to rely on the helper and Path handling, switch file existence checks to use a Path object, and add _dedup_key() to normalize deduplication on case-insensitive filesystems (Windows). Replace scattered os.path.expandvars/os.path.expanduser calls with the new helper for more predictable cross-platform behavior.
Adjust Harvester.update() error log string concatenation in gentl_backend.py to ensure proper spaces between message parts. Also remove an extraneous comment line from the gentl backend test to clean up test output.
@C-Achard C-Achard merged commit b6f3345 into cy/pre-release-fixes-2.0 Feb 25, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packaging Related to project packaging and release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Pre-release checklist

3 participants